(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery', 'datatables.net'], function ($) {
            return factory($, window, document);
        });
    } else if (typeof exports === 'object') {
        // CommonJS
        module.exports = function (root, $) {
            if (!root) {
                root = window;
            }
            if (!$ || !$.fn.dataTable) {
                $ = require('datatables.net')(root, $).$;
            }
            return factory($, root, root.document);
        };
    } else {
        // Browser
        factory(jQuery, window, document);
    }
}(function ($, window, document, undefined) {
    'use strict';
    var DataTable = $.fn.dataTable;

    if (!DataTable || !DataTable.ext) return;

    $.fn.dataTable.ext.errMode = 'none';
    $.fn.dataTable.ext.select2 = {
		language:'zh-CN',
        placeholder: {
            id: '-1',
            text: '请选择'
        },
        allowClear: true,
        minimumResultsForSearch: 5,
        templateResult: function (data) {
            return data.text || data.name || data.title || data.code || '请自定义显示';
        },
        templateSelection: function (data, container) {
            return data.text || data.name || data.title || data.code || '请自定义显示';
        },
        dropdownContainerCss: 'select2-container--default',
        ajax: {
            type: 'GET',
            delay: 250,
            dataType: "json",
            cache: true,
            data: function (params) {
                var t = {
                    search: params.term,
                    page: params.page || 0,
                    pageSize: params.pageSize || 100
                };
                return t;
            },
            processResults: function (data, params) {
                params.page = params.page || 0;
                params.pageSize = params.pageSize || 100;
                return {
                    results: data.items,
                    pagination: {
                        more: (params.page * params.pageSize) < data.total
                    }
                };
            }
        }
    };

    $.fn.dataTable.ext.kindEditor = {
        allowFileManager: true,
        autoHeightMode : true,
        afterCreate : function() {
            this.loadPlugin('autoheight');
        },
        afterBlur: function () { this.sync(); }
    };

    (function ($, DataTable) {
        if (!DataTable.ext.editorFields) {
            DataTable.ext.editorFields = {};
        }

        var Editor = DataTable.Editor;
        var _fieldTypes = DataTable.ext.editorFields;

        /**`
         * {
		 * 		label: '角色:',
		 *		name: 'appUserRoles[].id',
		 *		type: 'select2',
		 *		select2Opt: {} // select2 配置
		 *		events: {} // select2 支持的 Editor 事件
		 *	}
         */

        _fieldTypes.select2 = $.extend(true, {}, Editor.models.fieldType, {
            _addOptions: function (conf, opts, append) {
                var elOpts = conf._input[0].options, countOffset = 0;
                if (!append) {
                    elOpts.length = 0;
                    if (conf.placeholder !== undefined) {
                        var placeholderValue = conf.placeholderValue !== undefined ? conf.placeholderValue : '';
                        countOffset += 1;
                        elOpts[0] = new Option(conf.placeholder, placeholderValue);
                        var disabled = conf.placeholderDisabled !== undefined ? conf.placeholderDisabled : true;
                        elOpts[0].hidden = disabled;
                        elOpts[0].disabled = disabled;
                        elOpts[0]._editor_val = placeholderValue;
                    }
                } else {
                    countOffset = elOpts.length;
                }
                if (opts) {
                    Editor.pairs(opts, conf.optionsPair, function (val, label, i, attr) {
                        var option = new Option(label, val);
                        option._editor_val = val;
                        if (attr) {
                            $(option).attr(attr);
                        }
                        elOpts[i + countOffset] = option;
                    });
                }
            },
            create: function (conf) {
                var that = this;
                conf._enabled = true;
                var isMultiple = false;
                if (conf.select2Opt) {
                    isMultiple = conf.select2Opt.multiple || false;
                }

                var opt = $.extend(true, {}, $.fn.dataTable.ext.select2, conf.select2Opt);

                // Create the elements to use for the input
                conf._input = $('<select/>').attr({
                    id: Editor.safeId(conf.id),
                    class: 'DTE_Field_InputControl',
                    style: 'width: 100%',
                    multiple: isMultiple
                });


                _fieldTypes.select2._addOptions(conf, conf.options || conf.ipOpts);
                that.on('initComplete', function () {
                    //console.log('initComplete')
                    conf._input.select2(opt);
                }).on('preOpen', function () {
                    // console.log(opt);
                    // conf._input.select2(opt);
                }).on('initEdit', function (event, dom, data, element, type) {
                }).on('preBlur', function () {
                }).on('preClose', function () {
                    // _fieldTypes.select2.destroy(conf);
                });

                var events = conf.events;
                if (events) {
                    var $select2 = conf._input.select2(opt);
                    for (var event in events) {
                        $select2.on(event, events[event]);
                    }
                }
                return conf._input[0];
            },

            update: function (conf, options, append) {
                _fieldTypes.select2._addOptions(conf, options, append);
                var lastSet = conf._lastSet;
                if (lastSet !== undefined) {
                    _fieldTypes.select2.set(conf, lastSet, true);
                }
                conf._input.trigger('change');
            },
            get: function (conf) {
                return $(conf._input).val();
            },
            set: function (conf, val, localUpdate) {
                $(conf._input).val(val);
                if (!localUpdate) {
                    conf._input.trigger('change');
                }
            },
            enable: function (conf) {
                conf._enabled = true;
                $(conf._input).removeAttr('disabled');
            },
            disable: function (conf) {
                conf._enabled = false;
                $(conf._input).attr('disabled', 'disabled');
            },
            destroy: function (conf) {
                console.log('select2.destroy');
                conf._input.val(null).trigger("change")
            }
        });

        _fieldTypes.select2tree = $.extend(true, {}, Editor.models.fieldType, {
            _addOptions: function (conf, opts, append) {
                var elOpts = conf._input[0].options, countOffset = 0;
                if (!append) {
                    elOpts.length = 0;
                    if (conf.placeholder !== undefined) {
                        var placeholderValue = conf.placeholderValue !== undefined ? conf.placeholderValue : '';
                        countOffset += 1;
                        elOpts[0] = new Option(conf.placeholder, placeholderValue);
                        var disabled = conf.placeholderDisabled !== undefined ? conf.placeholderDisabled : true;
                        elOpts[0].hidden = disabled;
                        elOpts[0].disabled = disabled;
                        elOpts[0]._editor_val = placeholderValue;
                    }
                } else {
                    countOffset = elOpts.length;
                }
                if (opts) {
                    Editor.pairs(opts, conf.optionsPair, function (val, label, i, attr) {
                        var option = new Option(label, val);
                        option._editor_val = val;
                        if (attr) {
                            $(option).attr(attr);
                        }
                        elOpts[i + countOffset] = option;
                    });
                }
            },

            create: function (conf) {
                var that = this;
                conf._enabled = true;
                var isMultiple = false;
                if (conf.select2Opt) {
                    isMultiple = conf.select2Opt.multiple || false;
                }

                var opt = $.extend(true, {}, $.fn.dataTable.ext.select2, conf.select2Opt);

                // Create the elements to use for the input
                conf._input = $('<select/>').attr({
                    id: Editor.safeId(conf.id),
                    class: 'DTE_Field_InputControl',
                    style: 'width: 100%',
                    multiple: isMultiple
                });

                _fieldTypes.select2tree._addOptions(conf, conf.options || conf.ipOpts);
                that.on('initComplete', function () {
                    //console.log('initComplete')
                    conf._input.select2tree(opt);
                }).on('preOpen', function () {
                    // console.log(opt);
                    // conf._input.select2(opt);
                }).on('initEdit', function (event, dom, data, element, type) {
                }).on('preBlur', function () {
                }).on('preClose', function () {
                    // _fieldTypes.select2.destroy(conf);
                });

                return conf._input[0];
            },

            update: function (conf, options, append) {
                _fieldTypes.select2tree._addOptions(conf, options, append);
                var lastSet = conf._lastSet;
                if (lastSet !== undefined) {
                    _fieldTypes.select2tree.set(conf, lastSet, true);
                }
                conf._input.trigger('change');
            },

            get: function (conf) {
                return $(conf._input).val();
            },
            set: function (conf, val, localUpdate) {
                $(conf._input).val(val);
                if (!localUpdate)
                    conf._input.trigger('change');
            },
            enable: function (conf) {
                conf._enabled = true;
                $(conf._input).removeAttr('disabled');
            },
            disable: function (conf) {
                conf._enabled = false;
                $(conf._input).attr('disabled', 'disabled');
            },
            destroy: function (conf) {
                conf._input.val(null).trigger("change")
            }
        });

        _fieldTypes.kindEditor = $.extend(true, {}, Editor.models.fieldType, {
            create: function (conf) {
                var that = this;
                conf._enabled = true;

                var opt = $.extend(true, {}, $.fn.dataTable.ext.kindEditor, conf.kindEditorOpt);

                // Create the elements to use for the input
                conf._input = $('<textarea data-type="rich-textarea"></textarea>').attr({
                    id: Editor.safeId(conf.id),
                    class: 'DTE_Field_InputControl',
                    style: 'width: 100%'
                });


                that.on('initComplete', function () {
                }).on('open', function() {
                    try {
                        if (KindEditor) {
                            KindEditor.ready(function(K) {
                                K.create('#' + conf._input.attr('id'), opt);
                            });
                        }
                    } catch (e) {
                    }
                }).on('preOpen', function () {
                }).on('initEdit', function (event, dom, data, element, type) {
                }).on('preBlur', function () {
                }).on('preClose', function () {
                    try {
                        if (KindEditor) {
                            KindEditor.ready(function(K) {
                                K.remove('#' + conf._input.attr('id'));
                            });
                        }
                    } catch (e) {
                    }
                });

                var events = conf.events;
                if (events) {
                    var $select2 = conf._input.select2(opt);
                    for (var event in events) {
                        $select2.on(event, events[event]);
                    }
                }
                return conf._input[0];
            },

            get: function (conf) {
                return $(conf._input).val();
            },
            set: function (conf, val, localUpdate) {
                $(conf._input).val(val);
                if (!localUpdate) {
                    conf._input.trigger('change');
                }
            },
            enable: function (conf) {
                conf._enabled = true;
                $(conf._input).removeAttr('disabled');
            },
            disable: function (conf) {
                conf._enabled = false;
                $(conf._input).attr('disabled', 'disabled');
            },
            destroy: function (conf) {
                conf._input.val(null).trigger("change")
            }
        });

    })(jQuery, jQuery.fn.dataTable);


    $.extend(DataTable.defaults, {
//         dt 自带搜索框
//         dom: "<'row'<'col-12 col-md-6'l><'col-12 col-md-6'fB>><'row'<'col-12'tr>><'row'<'col-12 col-md-5'li><'col-12 col-md-7'p>>",
//         表上不带任何东西
//         dom: "<'row'<'col-12'tr>><'row'<'col-12 col-md-5'li><'col-12 col-md-7'p>>",
//         只有按钮
        dom: "<'row'<'col-12 mb-2'B>> <'row'<'col-12'tr>> <'d-flex justify-content-between'<li><p>>",
        renderer: 'bootstrap',
        processing: true,
        serverSide: true,
        responsive: true,
        autoWidth: true,
        language: {
            lengthMenu: '_MENU_ 条/页&nbsp;',
            pageLength: 10,
            info: '共 _TOTAL_ 条记录 ',
            infoEmpty: '暂无数据',
            infoFiltered: ' 过滤自 _MAX_ 条记录',
            emptyTable: '暂无数据',
            zeroRecords: '未找到匹配数据',
            loadingRecords: '正在加载……',
            processing: '正在处理……',
            search: '搜索',
            paginate: {
                previous: '<',
                next: '>',
                last: '>|',
                first: '|<',
                page: '页数: ',
                pageOf: '/'
            }
        },
        buttons: [
            {
                extend: 'collection',
                text: '<i class="fa fa-archive"></i> 导出 ',
                buttons: ['csv', 'excel', 'pdf', {
                    extend: 'print',
                    text: '打印'
                }]
            }
        ],
        ajax: {
            type: 'POST',
            timeout: 20000,
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (XMLHttpRequest && XMLHttpRequest.status === 901) {
                    top.location.href = '/admin/login';
                }
            },
            dataSrc: function (result) {
                var strJsonData = JSOG.stringify(result);
                var temp = JSOG.parse(strJsonData);
                return temp.data;
            }
        }
    });


    /* Default class modification */
    $.extend(DataTable.ext.classes, {
        sWrapper: 'dataTables_wrapper dt-bootstrap4',
        sInfo: 'dataTables_info d-inline-block',
        sLength: 'dataTables_length d-inline-block',
        sFilter: 'dataTables_filter d-inline-block',
        sFilterInput: 'form-control input-sm',
        sLengthSelect: 'form-control input-sm',
        sProcessing: 'dataTables_processing panel panel-default',
//		sPaging: 'dataTables_paginate pagination paging_',
//		sPageButton: 'paginate_button page-item'
    });


    $.extend(true, DataTable.Buttons.defaults, {
        dom: {
            button: {
                className: 'btn'
            }
        }
    });

    $.fn.DataTable.Editor.defaults && $.extend($.fn.DataTable.Editor.defaults, {
        idSrc: 'id',
        i18n: {
            create: {
                button: '创建',
                title: '创建记录',
                submit: '提交'
            },
            edit: {
                button: "编辑",
                title: "编辑记录",
                submit: '提交'
            },
            remove: {
                button: '删除',
                title: '删除',
                submit: '提交',
                confirm: {
                    '_': '确定删除 %d 条记录?',
                    '1': '确定删除 1 条记录?'
                }
            },
            error: {
                system: '系统异常。'
            },
            multi: {
                title: '多值',
                info: '选中的多条记录中该字段包含不同的值。如果需要将这些记录的该字段的值设置为同一值，点击输入，否则将保持之前不同的值。',
                restore: '撤销变更',
                noMulti: 'This input can be edited individually, but not part of a group.'
            },
            datetime: {
                previous: 'Prev',
                next: 'Next',
                months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
                weekdays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
                amPm: ['am', 'pm'],
                unknown: '-'
            }
        }
    });
    $.fn.DataTable.Editor.defaults && $.extend(true, $.fn.dataTable.Editor.classes, {
        header: {
            wrapper: 'DTE_Header modal-header'
        },
        body: {
            wrapper: 'DTE_Body modal-body'
        },
        footer: {
            wrapper: 'DTE_Footer modal-footer'
        },
        form: {
            tag: 'form-horizontal',
            button: 'btn'
        },
        field: {
            wrapper: 'DTE_Field form-group row mb-1 mb-md-2',
            label: 'col-12 col-md-3 col-form-label text-left text-md-right',
            input: 'col-12 col-md-9 controls float-right',
            error: 'error has-error',
            'msg-labelInfo': 'form-text',
            'msg-info': 'form-text',
            'msg-message': 'form-text',
            'msg-error': 'form-control-feedback text-danger',
            multiValue: 'well well-sm multi-value',
            multiInfo: 'small',
            multiRestore: 'well well-sm multi-restore'
        }
    });

    /*
     * API
     */
    var Api = $.fn.dataTable.Api;
    var apiRegister = Api.register;

    /*
     * 设置关联过滤表单
     * 设置过滤提交
     * 设置重置过滤
     */

    /**
     * 设置过滤表单，读取能够提交的元素的，input select 的值。
     */
    apiRegister('ext.filter.form()', function (selector) {
        var ctx = this.context[0];
        ctx.ext || (ctx.ext = {});
        ctx.ext.filter || (ctx.ext.filter = {});
        ctx.ext.filter.form = selector;
        return this;
    });

    /**
     * 参数设置
     *    name != null && value != null
     *        设值
     *    name != null && value == null && typeof name == 'string'
     *        取值
     *    name != null && value == null && typeof name == 'object'
     *        设值
     */
    apiRegister('ext.filter.param()', function (name, value) {
        var ctx = this.context[0];
        ctx.ext || (ctx.ext = {});
        ctx.ext.filter || (ctx.ext.filter = {});
        var param = ctx.ext.filter.param || {};

        if (name) {
            if (value) {
                param[name] = value;
            } else {
                if (typeof  name === 'string') {
                    return param[name];
                }
                if (typeof name === 'object') {
                    return $.extend(true, {}, param, name);
                }
            }
        }
        ctx.ext.filter.param = param;
    });

    apiRegister('ext.filter.clearParam()', function () {
        var ctx = this.context[0];
        ctx.ext || (ctx.ext = {});
        ctx.ext && ctx.ext.filter && ctx.ext.filter.param && (delete ctx.ext.filter.param);
        return this;
    });

    function form2json(selector) {
        var kvArray = $(selector).serializeArray();
        var result = {};

        function loop(hierarchy, index, object, value) {
            var name = hierarchy[index];
            if (hierarchy.length === index + 1) {
                object[name] = value;
            } else {
                if (!object[name]) {
                    object[name] = {};
                }
                loop(hierarchy, index + 1, object[name], value);
            }
        }

        $.map(kvArray, function (n, i) {
            // loop(n['name'].split('.'), 0, result, n['value']);
            var k = n['name'];
            var v = n['value'];
			v = v.trim();
			if (v) {
            if (result[k] === undefined) {
                result[k] = v;
            } else {
                var temp = [result[k]];
                temp.push(v);
                result[k] = temp;
            }
			}
        });

        return result;
    }

    /**
     * 提交处理，可手动设置提交数据，如果没有设置。值域覆盖说明，callback > param > filterForm
     */
    apiRegister('ext.filter.submit()', function (btn, cb) {
        var $this = this;
        var ctx = this.context[0];
        var ext = ctx.ext;
        ctx.ext || (ctx.ext = {});
        ctx.ext.filter || (ctx.ext.filter = {});

        function buildDataAndReload() {
            var paramData = ext.filter.param;
            var callback = typeof btn === 'function' ? btn : cb;
            var formData = form2json(ext.filter.form);
            var callData = callback ? callback() : {};
            var finalData = $.extend(true, {}, formData, paramData, callData);
            ctx.ajax.data || (ctx.ajax.data = {});
            ctx.ajax.data.filter = finalData;
            $this.ajax.reload();
        }

        if (btn) {
            $(btn).on('click', function () {
                buildDataAndReload();
            });
        } else {
            buildDataAndReload();
        }
    });

    /**
     * 获取选中的行的信息
     */
    apiRegister('ext.batchIds()', function (idSrc) {
        var $this = this;
        var ids = [];
        $this.rows().every(function (rowIdx, tableLoop, rowLoop) {
            $(this.node()).find('input[type=checkbox]').is(':checked') && ids.push(this.data()[idSrc || 'id']);
        });

        return ids;
    });

    /**
     * 获取选中的行
     */
    apiRegister('ext.batchRows()', function () {
        var $this = this;
        var rows = [];
        $this.rows().every(function (rowIdx, tableLoop, rowLoop) {
            $(this.node()).find('input[type=checkbox]').is(':checked') && rows.push(this.node());
        });
        return rows;
    });

    /**
     * 设置批量勾选
     */
    apiRegister('ext.batchCheck()', function (allChecks, checks) {
        var $this = this;
        $(allChecks).on('change', function () {
            $this.rows().every(function (rowIdx, tableLoop, rowLoop) {
                $(this.node()).find('input[type=checkbox]').prop('checked', $(allChecks).is(':checked'));
            });
        });
        checks = checks || 'input[type=checkbox]';
        $($this.table().body()).on('change', checks, function () {
            var isAllChecked = $(allChecks).is(':checked');
            var isThisChecked = $(this).is(':checked');
            if (isAllChecked !== isThisChecked) {
                $(allChecks).prop('checked', isThisChecked);
            }
            syncCheckStatus();
        });

        function syncCheckStatus() {
            var allOneStatus = true;
            var prevValue = undefined;
            $($this.table().body()).find(checks).each(function (element, index) {
                var currentValue = $(this).is(':checked');
                if (prevValue !== undefined) {
                    if (currentValue !== prevValue) {
                        allOneStatus = false;
                    }
                } else {
                    prevValue = currentValue;
                }
            });

            if (allOneStatus) {
                $(allChecks).prop('checked', prevValue);
            } else {
                $(allChecks).prop('checked', false);
            }
        }

        return this;
    });

    return DataTable;
}))
;

try {
    if (KindEditor) {
        KindEditor.ready(function(K) {
            console.log('ke init from root');
            $('[data-type="rich-textarea"]').each(function () {
            K.create('#' + $(this).attr('id'), {});
            });
        });
    }
} catch (e) {
}